package com.huike.clues.service.impl;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;


import io.minio.*;
import io.minio.errors.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import com.huike.clues.service.ISysFileService;
import com.huike.common.config.MinioConfig;
import com.huike.common.core.domain.AjaxResult;

import lombok.extern.slf4j.Slf4j;

@Service
@Slf4j
public class SysFileServiceImpl implements ISysFileService {


    @Autowired
    MinioConfig minioConfig;


    /**
     * 文件上传至Minio
     * 使用try catch finally进行上传
     * finally里进行资源的回收
     */
    @Override
    public AjaxResult upload(MultipartFile file) {
//		InputStream inputStream = null;
        //创建Minio的连接对象
//		MinioClient minioClient = getClient();
//		String bucketName = minioConfig.getBucketName();
//		try {
//			inputStream = file.getInputStream();
//			//基于官网的内容，判断文件存储的桶是否存在 如果桶不存在就创建桶
//			boolean found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("huike-crm").build());
//			if(!found){
//				minioClient.makeBucket(MakeBucketArgs.builder().bucket("huike-crm").build());
//			}else {
//				log.info("该桶已经存在");
//			}
//			//TODO 补全这部分代码
//			/**
//			 * ================================操作文件================================
//			 * 思路：我们上传的文件是:合同.pdf
//			 * 那么我们应该上传到配置的bucket内 我们配置的bucketName是huike-crm
//			 * 那么我们存在桶里的文件应该是什么样的 也叫“合同.pdf”吗?
//			 * 应该按照上传的年月日进行区分
//			 * 举例：2021-05-05日进行上传的
//			 * 那么存在桶里的路径应该是
//			 * huike-crm/2021/05/05/这个目录下
//			 * 而对于同一个文件，存在重名问题，所以我们应该利用UUID生成一个新的文件名，并拼接上 .pdf 作为文件后缀
//			 * 那么完整的路径就是 huike-crm/2021/05/05/uuid.pdf
//			 *
//			 * 如果上述思路你无法理解，那么就直接存放在桶内生成uuid+.pdf即可
//			 * 即：huike-crm/uuid.pdf
//			 */
//			//TODO 基于上述逻辑补全代码
//			String fileName = file.getOriginalFilename();
//			String objectName = new SimpleDateFormat("yyyy/MM/dd/").format(new Date()) + UUID
//					.randomUUID().toString()
//					.replaceAll("-", "")
//					+ fileName.substring(fileName.lastIndexOf("."));
//			// 文件的上传
//			PutObjectArgs objectArgs = PutObjectArgs.builder().object(objectName)
//					.bucket(bucketName)
//					.contentType(file.getContentType())
//					.stream(file.getInputStream(),file.getSize(),-1).build();
//			minioClient.putObject(objectArgs);
//
//
//			/**
//			 * 构建返回结果集
//			 */
//			AjaxResult ajax = AjaxResult.success();
//			/**
//			 * 封装需要的数据进行返回
//			 */
//			ajax.put("fileName", "/"+bucketName+"/"+objectName);
//			//url需要进行截取
//			ajax.put("url", minioConfig.getEndpoint()+":"+ minioConfig.getPort()+"/"+ minioConfig.getBucketName()+"/"+fileName);
//			return ajax;
//		}catch(Exception e){
//			e.printStackTrace();
//			return AjaxResult.error("上传失败");
//		}finally {
//			//防止内存泄漏
//			if (inputStream != null) {
//				try {
//					inputStream.close(); // 关闭流
//				} catch (IOException e) {
//					log.debug("inputStream close IOException:" + e.getMessage());
//				}
//			}
//		}

        // 1. 创建MInioClient连接对象

//		MinioClient minioClient = getClient();
//		String bucketName = minioConfig.getBucketName();
//		InputStream inputStream = null;
//
//		// 2. 判断bucketName是否存在
//		try {
//			boolean isExist  = minioClient.bucketExists(BucketExistsArgs.builder().bucket("huike-crm").build());
//			if(!isExist){
//				minioClient.makeBucket(MakeBucketArgs.builder().bucket("huike-crm").build());
//			}else {
//				log.info(bucketName+"is already exist");
//			}
//			// 3. 得到文件的输入流
//			 inputStream = file.getInputStream();
//			// 4. 处理文件的名称
//			String originalFilename = file.getOriginalFilename(); // 源文件名称
//			SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
//			// 格式化当前的时间
//			String date = sdf.format(new Date());
//			String uuid = UUID.randomUUID().toString();
//			// uuid改造后的名称
//			String uuidName = uuid.replaceAll("-", "");
//			String substring = originalFilename.substring(originalFilename.lastIndexOf("."));
//			// 最终的名称
//			String targetName = date + uuidName + substring;
//			// 5. 上传到minio
//			PutObjectArgs putObjectArgs = PutObjectArgs.builder()
//					.object(targetName)
//					.bucket("huike-crm")
//					.contentType(file.getContentType())
//					.stream(inputStream, file.getSize(), -1)
//					.build();
//
//			minioClient.putObject(putObjectArgs);
//
//			// 6. 构造返回值 , 返回文件的名称和路径
//			AjaxResult ajaxResult = AjaxResult.success();
//			ajaxResult.put("fileName" , "/"+bucketName+"/"+targetName);
//			ajaxResult.put("url" , minioConfig.getEndpoint()+":" + minioConfig.getPort()+"/"+minioConfig.getBucketName()+"/"+originalFilename);
//			return ajaxResult;
//		} catch (Exception e) {
//			e.printStackTrace();
//			return AjaxResult.error("上传失败");
//		}finally {
//
//			// 防止内存泄露
//			if(inputStream != null){
//				try {
//					inputStream.close();
//				} catch (IOException e) {
//					log.info("关流失败");
//				}
//			}
//		}

        MinioClient minioClient = getClient();
        String bucketName = minioConfig.getBucketName();
        InputStream inputStream = null;

        try {

            boolean isExist = minioClient.bucketExists(BucketExistsArgs.builder().bucket("huike-crm").build());
            if (!isExist) {
                minioClient.makeBucket(MakeBucketArgs.builder().bucket("huike-crm").build());
            } else {
                log.info(bucketName + "is already exist");
            }

            String originalFilename = file.getOriginalFilename();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/");
            String format = sdf.format(new Date());
            String uuid = UUID.randomUUID().toString().replaceAll("-", "");
            String tragetName = format + uuid + originalFilename.substring(originalFilename.lastIndexOf("."));

            // 上传文件
            inputStream = file.getInputStream();
            minioClient.putObject(PutObjectArgs.builder().object(tragetName).bucket(bucketName).contentType(file.getContentType()).stream(inputStream, file.getSize(), -1).build());
            AjaxResult ajaxResult = AjaxResult.success();
            ajaxResult.put("fileName", "/" + bucketName + "/" + tragetName);
            ajaxResult.put("url", minioConfig.getEndpoint() + ":" + minioConfig.getPort() + "/" + bucketName + "/" + originalFilename);
            return ajaxResult;


        } catch (Exception e) {
            e.printStackTrace();
            return AjaxResult.error("上传失败");
        } finally {
            // 防止内存溢出
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                    log.info("关流失败");
                }
            }
        }


    }


    /**
     * 免费提供一个获取Minio连接的方法
     * 获取Minio连接
     *
     * @return
     */
    private MinioClient getClient() {
        MinioClient minioClient =
                MinioClient.builder()
                        .endpoint("http://" + minioConfig.getEndpoint() + ":" + minioConfig.getPort())
                        .credentials(minioConfig.getAccessKey(), minioConfig.getSecretKey())
                        .build();
        return minioClient;
    }


}
